/*
 * Copyright (c) 2016 Breezee.org. All Rights Reserved.
 */

package com.oj.common.event;

import com.oj.common.exception.EventException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.EventListener;

/**
 * 事件监听器
 *
 * @author Silence
 * @date 2016/4/28
 */
public abstract class AbstractEventListener implements EventListener, Comparable<AbstractEventListener> {

    private final static Logger LOGGER = LoggerFactory.getLogger(AbstractEventListener.class);

    /**
     * 是否可用
     */
    protected boolean enable = true;

    /**
     * 排序号
     * 从小到大
     */
    protected int sortNo = 0;

    /**
     * 监听名称
     */
    protected String name;

    /**
     * 状态
     */
    protected ListenerStatus status = ListenerStatus.INIT;



    /**
     * 是否接受此事件
     *
     * @param event 事件信息
     * @return 是否接受此事件
     */
    protected abstract boolean accept(EventInfo event);

    /**
     * 真正处理事件的逻辑
     *
     * @param event 需要处理的事件信息
     */
    protected abstract void handle(EventInfo event) throws EventException;

    /**
     * 事件处理前
     *
     * @param event 事件信息
     */
    protected void beforeHandle(EventInfo event) {
        //子类中实现
        event.eventStatus = EventStatus.ONGO;
    }

    /**
     * 事件处理完成后
     * 此方法在有异常抛出时候，不会被执行
     *
     * @param event 事件信息
     */
    protected void afterHandle(EventInfo event) {
        //子类中实现
        event.eventStatus = EventStatus.COMPLETE;
    }

    /**
     * 异常发生时的处理方法
     * 一般我们可以在此定义补偿机制实现回退操作
     *
     * @param event 事件信息
     * @param ex    异常信息
     */
    protected void exceptionHandle(EventInfo event, EventException ex) {
        //子类中实现
        event.eventStatus = EventStatus.INTERRUPT;
    }

    /**
     * 处理事件
     *
     * @param event 事件信息
     */
    public void onEvent(EventInfo event) throws EventException {
        this.status = ListenerStatus.ACCEPT;
        if (event.getEventStatus() == EventStatus.DONE) {
            return;
        }
        if (isEnable() && accept(event)) {
            LOGGER.info("======== Listener Name:" + getName() + ", sortNo:" + getSortNo() + " is executed ===========");
            this.status = ListenerStatus.HANDLE;
            beforeHandle(event);
            try {
                handle(event);
            } catch (EventException e) {
                this.status = ListenerStatus.EXCEPTION;
                exceptionHandle(event, e);
                throw e;
            }
            afterHandle(event);
            this.status = ListenerStatus.COMPLETE;
        }else{
            this.status = ListenerStatus.NOTACCEPT;
        }
    }

    @Override
    public int compareTo(AbstractEventListener listener) {
        if (listener != null) {
            int t = this.getSortNo() - listener.getSortNo();
            return t == 0 ? 1 : t;
        }
        return 0;
    }

    public int getSortNo() {
        return sortNo;
    }

    public void setSortNo(int sortNo) {
        this.sortNo = sortNo;
    }

    public boolean isEnable() {
        return enable;
    }

    public void setEnable(boolean enable) {
        this.enable = enable;
    }

    public String getName() {
        if (name == null) {
            return this.getClass().getSimpleName();
        }
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStatus(){
        return this.status.getText();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof AbstractEventListener)) {
            return false;
        }
        AbstractEventListener that = (AbstractEventListener) o;
        return enable == that.enable && sortNo == that.sortNo && (name != null ? name.equals(that.name) : that.name == null);
    }

    @Override
    public int hashCode() {
        int result = (enable ? 1 : 0);
        result = 31 * result + sortNo;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}
